package com.bstek.uflo.client.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.http.ResponseEntity;

import com.bstek.uflo.client.model.ProcessVariablesInfo;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.model.ProcessDefinition;
import com.bstek.uflo.model.ProcessInstance;
import com.bstek.uflo.model.variable.Variable;
import com.bstek.uflo.query.ProcessInstanceQuery;
import com.bstek.uflo.query.ProcessQuery;
import com.bstek.uflo.query.ProcessVariableQuery;
import com.bstek.uflo.service.ProcessService;
import com.bstek.uflo.service.RestService;
import com.bstek.uflo.service.StartProcessInfo;

public class ProcessClientImpl implements ProcessClient {
	private RestService rest;
	private ProcessService processService;

	public ProcessDefinition getProcessById(long processId) {
		return this.processService.getProcessById(processId);
	}

	public ProcessDefinition getProcessByKey(String key) {
		return this.processService.getProcessByKey(key);
	}

	public ProcessDefinition getProcessByName(String processName) {
		return this.processService.getProcessByName(processName);
	}

	public ProcessDefinition getProcessByName(String processName, int version) {
		return this.processService.getProcessByName(processName, version);
	}

	public ProcessInstance startProcessById(long processId, StartProcessInfo startProcessInfo) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/process/start/id/" + processId + "";
			ResponseEntity<ProcessInstance> responseEntity = this.rest.post(uri, startProcessInfo,
					ProcessInstance.class);
			return (ProcessInstance) responseEntity.getBody();
		}
		return this.processService.startProcessById(processId, startProcessInfo);
	}

	public ProcessInstance startProcessByKey(String key, StartProcessInfo startProcessInfo) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/process/start/key/" + key + "";
			ResponseEntity<ProcessInstance> responseEntity = this.rest.post(uri, startProcessInfo,
					ProcessInstance.class);
			return (ProcessInstance) responseEntity.getBody();
		}
		return this.processService.startProcessByKey(key, startProcessInfo);
	}

	public ProcessInstance startProcessByName(String processName, StartProcessInfo startProcessInfo) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/process/start/name/" + processName + "";
			ResponseEntity<ProcessInstance> responseEntity = this.rest.post(uri, startProcessInfo,
					ProcessInstance.class);
			return (ProcessInstance) responseEntity.getBody();
		}
		return this.processService.startProcessByName(processName, startProcessInfo);
	}

	public void deleteProcessInstanceById(long processInstanceId) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/processinstance/delete/" + processInstanceId + "";
			this.rest.post(uri, null, null);
		} else {
			this.processService.deleteProcessInstanceById(processInstanceId);
		}
	}

	public void saveProcessVariable(long processInstanceId, String key, Object value) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			Map<String, Object>  variables = new HashMap<String, Object> ();
			variables.put(key, value);
			saveProcessVariables(processInstanceId, variables);
		} else {
			this.processService.saveProcessVariable(processInstanceId, key, value);
		}
	}

	public void saveProcessVariables(long processInstanceId, Map<String, Object> variables) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/processinstance/variables/save/" + processInstanceId + "";
			ProcessVariablesInfo info = new ProcessVariablesInfo();
			info.setVariables(variables);
			this.rest.post(uri, info, null);
		} else {
			this.processService.saveProcessVariables(processInstanceId, variables);
		}
	}

	public void deleteProcessVariable(String key, long processInstanceId) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/processinstance/variable/delete/" + key + "/" + processInstanceId + "";
			this.rest.post(uri, null, null);
		} else {
			this.processService.deleteProcessInstanceById(processInstanceId);
		}
	}

	public ProcessInstance getProcessInstanceById(long processInstanceId) {
		return this.processService.getProcessInstanceById(processInstanceId);
	}

	public List<Variable> getProcessVariables(long processInsanceId) {
		return this.processService.getProcessVariables(processInsanceId);
	}

	public List<Variable> getProcessVariables(ProcessInstance processInsance) {
		return this.processService.getProcessVariables(processInsance);
	}

	public Object getProcessVariable(String key, ProcessInstance processInstance) {
		return this.processService.getProcessVariable(key, processInstance);
	}

	public Object getProcessVariable(String key, long processInsanceId) {
		return this.processService.getProcessVariable(key, processInsanceId);
	}

	public ProcessInstanceQuery createProcessInstanceQuery() {
		return this.processService.createProcessInstanceQuery();
	}

	public ProcessVariableQuery createProcessVariableQuery() {
		return this.processService.createProcessVariableQuery();
	}

	public ProcessQuery createProcessQuery() {
		return this.processService.createProcessQuery();
	}

	public void deleteProcess(long processId) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/process/delete/id/" + processId + "";
			this.rest.post(uri, null, null);
			this.processService.deleteProcessFromMemory(processId);
		} else {
			this.processService.deleteProcess(processId);
		}
	}

	public void deleteProcess(String processKey) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/process/delete/key/" + processKey + "";
			this.rest.post(uri, null, null);
			this.processService.deleteProcessFromMemory(processKey);
		} else {
			this.processService.deleteProcess(processKey);
		}
	}

	public void deleteProcess(ProcessDefinition processDefinition) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/process/delete/id/" + processDefinition.getId() + "";
			this.rest.post(uri, null, null);
			this.processService.deleteProcessFromMemory(processDefinition.getId());
		} else {
			this.processService.deleteProcess(processDefinition);
		}
	}

	public RestService getRest() {
		return this.rest;
	}

	public void setRest(RestService rest) {
		this.rest = rest;
	}

	public ProcessService getProcessService() {
		return this.processService;
	}

	public void setProcessService(ProcessService processService) {
		this.processService = processService;
	}
}